﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO.Ports;
using System.Threading;

namespace zy_simu.Data
{
    public class EmuCommUart : IEmuComm
    {
        private SerialPort com;
        
        private byte[] rx_buf = new byte[4096];
        private int rx_buf_pos = 0;

        //public System.Threading.Thread ReadThread;
        public EmuCommUart(string com_str) 
        {
            com = new SerialPort(com_str);
        }
        private void data_recv(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] buf = new byte[4096];
            int len = 0;

            try
            {
                len = com.Read(buf, 0, buf.Length);
            }
            catch (Exception excp)
            {
                Console.WriteLine("uart read Error: {0}", excp.Message);
            }
            if (len <= 0) return;
            lock (rx_buf)
            {
                if (len <= rx_buf.Length - rx_buf_pos)
                {
                    Array.Copy(buf, 0, rx_buf, rx_buf_pos, len);
                    rx_buf_pos += len;
                }
            }
        }

        // 实现IEmuComm -----------------------------------------------------------
        public async Task<bool> Open()
        {
            //com.BaudRate = 921600;
            com.BaudRate = 115200;
            com.Parity = Parity.None;
            com.StopBits = StopBits.One;
            com.DataBits = 8;
            com.DataReceived += data_recv;
            com.WriteTimeout = 10;
            com.Open();
            return true;
        }
        public async Task<bool> Close()
        {
            com.Close();
            return true;
        }

        public async Task Send(byte[] buf, int cnt)
        {
            if(com.IsOpen)
            {
                try
                {
                    com.Write(buf, 0, cnt);
                }
                catch (Exception ex)
                {
                    System.Console.WriteLine(ex.ToString()); 
                }
            }
        }
        public int Recv(byte[] buf, int offset, int cnt)
        {
            lock (rx_buf)
            {
                cnt = (cnt > rx_buf_pos) ? rx_buf_pos : cnt;
                Array.Copy(rx_buf, 0, buf, offset, cnt);
                rx_buf_pos -= cnt;
                return cnt;
            }
        }
    }
}
